package chapter_20


trait RationalTrait {
  /*
  懒加载有一个很重要的属性：定义的文本顺序不用多加考虑，因为初始化是按需的。从而，懒加载
  val可以免去你作为程序员不得不认真考虑的问题，即如何安排val定义顺序，以确保所有东西在
  需要的时候已经完成定义。
  然而，这种好处仅在于懒加载val的初始化不会产生副作用且更不能依赖与此的前提下。如果
  存在副作用，那么初始化的顺序就值得考虑了。并且在这种情况下，想要像前面的例子里演示的那样
  跟踪初始化的顺序将变得非常困难。因此懒加载val是对函数式对象的锦上添花，这里初始化的顺序
  问题无足轻重，只要最后所有的东西都完成初始化就好。它们并不适合于主要为指令式代码的情况。
   */
  val numerArg: Int
  val denomArg: Int
  private lazy val g = {
    require(denomArg != 0)
    gcd(numerArg, denomArg)
  }
  lazy val numer = numerArg / g
  lazy val denom = denomArg / g

  private def gcd(a: Int, b: Int): Int =
    if (b == 0) a else gcd(b, a % b)

  override def toString: String = numer + "/" + denom
}


class RationalClass(n: Int, d: Int) extends {
  val numerArg = n
  val denomArg = d
} with RationalTrait {
  def +(that: RationalClass) = new RationalClass(
    numer * that.denom + that.numer * denom,
    denom * that.denom
  )
}


object RationalTraitApp {

  def main(args: Array[String]): Unit = {

    // 懒加载val
    val x= 2
    new RationalTrait {
      override val numerArg: Int = 1 * x
      override val denomArg: Int = 2 * x
    }
  }
}
